﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Transactions;

namespace LogicUniversityBiz
{
    public class IssueAdjustmentVoucher
    {
        private int voucherID;
        LogicUniversityEntities en = new LogicUniversityEntities();

        public List<Discrepancy> getAdjustmentIssue()
        {
            var query = from ad in en.Adjustment_Voucher
                        join vd in en.Voucher_Detail
                        on ad.Voucher_ID equals vd.Voucher_ID
                        where ad.Approved_By == null &&
                        vd.Total_Cost<=250
                        select new Discrepancy()
                        {
                            VoucherID=ad.Voucher_ID,
                            ItemCode=vd.Item_Code,
                            QuantityAdj=vd.Quantity_Adjusted,
                            Reason=vd.Reason,
                            TotalCost=(decimal)vd.Total_Cost
                        };

            return query.ToList();
        }

        public List<Discrepancy> getAdjustmentIssueAbove()
        {
            var query = from ad in en.Adjustment_Voucher
                        join vd in en.Voucher_Detail
                        on ad.Voucher_ID equals vd.Voucher_ID
                        where ad.Approved_By == null &&
                        vd.Total_Cost >= 250
                        select new Discrepancy()
                        {
                            VoucherID = ad.Voucher_ID,
                            ItemCode = vd.Item_Code,
                            QuantityAdj = vd.Quantity_Adjusted,
                            Reason = vd.Reason,
                            TotalCost = (decimal)vd.Total_Cost
                        };

            return query.ToList();
        }

        public List<Catelogue> getItemCode()
        {

            var itemCode = en.Catelogues.AsEnumerable().Select(x => x).ToList();
            return itemCode;
        }

        public void addAdjustmentVoucher(Adjustment_Voucher av)
        {
          
                using (TransactionScope scope = new TransactionScope())
                {
                    try
                    {
                        en.Adjustment_Voucher.AddObject(av);
                        foreach (Voucher_Detail detail in av.Voucher_Detail)
                        {
                            addIssue(detail);
                        }

                        en.SaveChanges();
                        scope.Complete();
                    }
                    catch (Exception e)
                    {
                        return;
                    }
                }
            
        }

        public void addIssue(Voucher_Detail detail)
        {

            detail.Status = "Pending";
                en.Voucher_Detail.AddObject(detail);
           
        }

        public void approveAdjustments(HashSet<int> set,string approvedBy)
        {
            List<Voucher_Detail> detailsList = new List<Voucher_Detail>();
            foreach(int id in set)
            {
                var voucherQuery = from av in en.Adjustment_Voucher
                                   where av.Voucher_ID == id
                                   select av;

                Adjustment_Voucher voucher = voucherQuery.SingleOrDefault();
                voucher.Approved_By = approvedBy;

                var detailQuery = from detail in en.Voucher_Detail
                                  where detail.Voucher_ID == id
                                  select detail;

                foreach (Voucher_Detail detail in detailQuery.ToList())
                {
                    detail.Status = "Approved";
                    detailsList.Add(detail);

                    updateStockCard(detail, voucher.IssuedDate);
                }
            }

        }
        public int lastStockCardID()
        {
            var query = (from stock in en.Stock_Card
                         select stock.StockCard_ID).Max();

            return query;
        }

        public void updateStockCard(Voucher_Detail detail,DateTime issueDate)
        {
            string itemCode = detail.Item_Code;

            var stockQuery = (from stock in en.Stock_Card
                              where stock.Item_Code == itemCode
                              select stock.StockCard_ID).SingleOrDefault();

            if (stockQuery == 0)
            {
                Stock_Card stock = new Stock_Card();
                stock.Item_Code = itemCode;
                en.Stock_Card.AddObject(stock);

                en.SaveChanges();

                int lastStockID = lastStockCardID();
                updateStockDetail(detail, issueDate, lastStockID);
            }
            else
            {
                int stockID = stockQuery;
                updateStockDetail(detail, issueDate, stockID);
            }
        }

        public void updateStockDetail(Voucher_Detail detail,DateTime issueDate,int stockID)
        {
            Stock_Card_Detail StockDetail = new Stock_Card_Detail();
            StockDetail.Date = issueDate;
            StockDetail.Quantity = detail.Quantity_Adjusted;
            StockDetail.Description = detail.Reason;
            StockDetail.Stock_Card_ID = stockID;

            StockDetail.Balance = getCurrentBalanceOf(detail.Item_Code) + detail.Quantity_Adjusted;

            Catelogue cat = getCatelogueOf(detail.Item_Code);
            cat.Balance = StockDetail.Balance;

            en.Stock_Card_Detail.AddObject(StockDetail);
            en.SaveChanges();
        }

        public int getCurrentBalanceOf(string itemCode)
        {
            var query = from c in en.Catelogues
                        where c.Item_Code == itemCode
                        select c.Balance;

            return query.Single();
        }

        public Catelogue getCatelogueOf(string itemCode)
        {
            var query = from c in en.Catelogues
                        where c.Item_Code == itemCode
                        select c;

            return query.Single();
        }
    }
}
